package flare.query
{
  /**
   * Expression operator for an if statement that performs conditional
   * execution.
   */
  public class If extends Expression
  {
    private var _test:Expression;
    private var _then:Expression;
    private var _else:Expression;

    /** The conditional clause of the if statement. */
    public function get test():Expression
    {
      return _test;
    }

    public function set test(e:*):void
    {
      _test = Expression.expr(e);
    }

    /** Sub-expression evaluated if the test condition is true. */
    public function get then():Expression
    {
      return _then;
    }

    public function set then(e:*):void
    {
      _then = Expression.expr(e);
    }

    /** Sub-expression evaluated if the test condition is false. */
    public function get els():Expression
    {
      return _else;
    }

    public function set els(e:*):void
    {
      _else = Expression.expr(e);
    }

    /**
   * @inheritDoc
   */
    public override function get numChildren():int
    {
      return 3;
    }

    // --------------------------------------------------------------------

    /**
     * Create a new IfExpression.
     * @param test the test expression for the if statement
     * @param thenExpr the expression to evaluate if the test predicate
     * evaluates to true
     * @param elseExpr the expression to evaluate if the test predicate
     * evaluates to false
     */
    public function If(test:*, thenExpr:*, elseExpr:*)
    {
      this.test = test;
      this.then = thenExpr;
      this.els = elseExpr;
    }

    /**
   * @inheritDoc
   */
    public override function clone():Expression
    {
      return new If(_test.clone(), _then.clone(), _else.clone());
    }

    /**
   * @inheritDoc
   */
    public override function eval(o:Object = null):*
    {
      return (_test.predicate(o) ? _then : _else).eval(o);
    }

    /**
     * @inheritDoc
     */
    public override function getChildAt(idx:int):Expression
    {
      switch (idx)
      {
        case 0: return _test;
        case 1: return _then;

        case 2: return _else;
        default: return null;
      }
    }

    /**
     * @inheritDoc
     */
    public override function setChildAt(idx:int, expr:Expression):Boolean
    {
      switch (idx)
      {
        case 0:
          _test = expr;
        return true;
        case 1:
          _then = expr;
        return true;

        case 2: _else = expr;
        return true;
        default: return false;
      }
    }

    /**
     * @inheritDoc
     */
    public override function toString():String
    {
      return "IF " + _test.toString() + " THEN " + _then.toString() + " ELSE " + _else.toString();
    }
  } // end of class If
}